//
// Created by Finchen on 2025/9/4.
//

#include "PositionConfigDialog.h"
#include <QTableWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QFileDialog>
#include <QMessageBox>
#include <QInputDialog>
#include <QFormLayout>
#include <QDialogButtonBox>
#include <QDoubleSpinBox>
#include <QStandardPaths>
#include <QDir>
#include <algorithm>

PositionConfigDialog::PositionConfigDialog(QWidget *parent)
    : QDialog(parent)
    , m_tableWidget(nullptr)
{
    setWindowTitle("Configure Positions");
    setWindowIcon(QIcon(":/icons/configure.png"));
    resize(500, 400);

    setupUI();
    connectSignals();
    updateButtons();
}

PositionConfigDialog::~PositionConfigDialog() = default;

void PositionConfigDialog::setupUI() {
    setupTable();
    setupButtons();

    auto *mainLayout = new QVBoxLayout(this);
    auto *contentLayout = new QHBoxLayout();
    contentLayout->addWidget(m_tableWidget, 1);

    auto *buttonLayout = new QVBoxLayout();
    buttonLayout->addWidget(m_loadButton);
    buttonLayout->addWidget(m_clearButton);
    buttonLayout->addWidget(m_addButton);
    buttonLayout->addWidget(m_fromToButton);
    buttonLayout->addWidget(m_deleteButton);
    buttonLayout->addWidget(m_moveUpButton);
    buttonLayout->addWidget(m_moveDownButton);
    buttonLayout->addWidget(m_sortAscButton);
    buttonLayout->addWidget(m_sortDescButton);
    buttonLayout->addStretch();

    contentLayout->addLayout(buttonLayout);
    mainLayout->addLayout(contentLayout);

    auto *dialogButtonLayout = new QHBoxLayout();
    dialogButtonLayout->addStretch();
    dialogButtonLayout->addWidget(m_okButton);
    dialogButtonLayout->addWidget(m_cancelButton);

    mainLayout->addLayout(dialogButtonLayout);
}

void PositionConfigDialog::setupTable() {
    m_tableWidget = new QTableWidget(this);
    m_tableWidget->setColumnCount(2);
    m_tableWidget->setHorizontalHeaderLabels(QStringList() << "Nr" << "Position [mm]");
    m_tableWidget->horizontalHeader()->setStretchLastSection(true);
    m_tableWidget->setColumnWidth(0, 60);
    m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
}

void PositionConfigDialog::setupButtons() {
    m_loadButton = new QPushButton("📁 Load...", this);
    m_clearButton = new QPushButton("🗑️ Clear", this);
    m_addButton = new QPushButton("➕ Add", this);
    m_fromToButton = new QPushButton("➕ From...To", this);
    m_deleteButton = new QPushButton("❌ Delete", this);
    m_moveUpButton = new QPushButton("⬆️ Move Up", this);
    m_moveDownButton = new QPushButton("⬇️ Move Down", this);
    m_sortAscButton = new QPushButton("🔄 ↑", this);
    m_sortDescButton = new QPushButton("🔄 ↓", this);
    m_okButton = new QPushButton("✅ OK", this);
    m_cancelButton = new QPushButton("❌ Cancel", this);

    const QSize buttonSize(100, 30);
    for (auto *button : {m_loadButton, m_clearButton, m_addButton, m_fromToButton,
                         m_deleteButton, m_moveUpButton, m_moveDownButton,
                         m_sortAscButton, m_sortDescButton}) {
        button->setMinimumSize(buttonSize);
    }
    m_okButton->setMinimumSize(80, 30);
    m_cancelButton->setMinimumSize(80, 30);
}

void PositionConfigDialog::connectSignals() {
    connect(m_loadButton, &QPushButton::clicked, this, &PositionConfigDialog::onLoadClicked);
    connect(m_clearButton, &QPushButton::clicked, this, &PositionConfigDialog::onClearClicked);
    connect(m_addButton, &QPushButton::clicked, this, &PositionConfigDialog::onAddClicked);
    connect(m_fromToButton, &QPushButton::clicked, this, &PositionConfigDialog::onFromToClicked);
    connect(m_deleteButton, &QPushButton::clicked, this, &PositionConfigDialog::onDeleteClicked);
    connect(m_moveUpButton, &QPushButton::clicked, this, &PositionConfigDialog::onMoveUpClicked);
    connect(m_moveDownButton, &QPushButton::clicked, this, &PositionConfigDialog::onMoveDownClicked);
    connect(m_sortAscButton, &QPushButton::clicked, this, &PositionConfigDialog::onSortAscendingClicked);
    connect(m_sortDescButton, &QPushButton::clicked, this, &PositionConfigDialog::onSortDescendingClicked);
    connect(m_okButton, &QPushButton::clicked, this, &QDialog::accept);
    connect(m_cancelButton, &QPushButton::clicked, this, &QDialog::reject);
    connect(m_tableWidget, &QTableWidget::itemSelectionChanged, this, &PositionConfigDialog::updateButtons);
}

void PositionConfigDialog::setPositions(const QVector<double>& positions) {
    m_positions = positions;
    refreshTable();
}

QVector<double> PositionConfigDialog::getPositions() const {
    return m_positions;
}

void PositionConfigDialog::onLoadClicked() {
    QString fileName = QFileDialog::getOpenFileName(
        this, "Load Measurement Positions",
        QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation),
        "M2 Files (*.m2);;All Files (*)");
    if (!fileName.isEmpty()) {
        QMessageBox::information(this, "Info", "Load functionality will be implemented based on .m2 file format");
    }
}

void PositionConfigDialog::onClearClicked() {
    if (QMessageBox::question(this, "Clear Positions", "Are you sure you want to clear all positions?",
                              QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
        m_positions.clear();
        refreshTable();
    }
}

void PositionConfigDialog::onAddClicked() {
    bool ok;
    double position = QInputDialog::getDouble(this, "Add Position", "Position [mm]:", 0.0, -1000.0, 1000.0, 3, &ok);
    if (ok) {
        addPosition(position);
    }
}

void PositionConfigDialog::onFromToClicked() {
    QDialog dialog(this);
    dialog.setWindowTitle("Generate Positions");
    auto *layout = new QFormLayout(&dialog);
    auto *fromSpinBox = new QDoubleSpinBox();
    auto *toSpinBox = new QDoubleSpinBox();
    auto *stepSpinBox = new QDoubleSpinBox();
    fromSpinBox->setRange(-1000, 1000);
    toSpinBox->setRange(-1000, 1000);
    stepSpinBox->setRange(0.001, 100);
    stepSpinBox->setValue(1.0);
    layout->addRow("From [mm]:", fromSpinBox);
    layout->addRow("To [mm]:", toSpinBox);
    layout->addRow("Step [mm]:", stepSpinBox);
    auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
    connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
    layout->addWidget(buttonBox);
    if (dialog.exec() == QDialog::Accepted) {
        double from = fromSpinBox->value();
        double to = toSpinBox->value();
        double step = stepSpinBox->value();
        if (from > to) std::swap(from, to);
        for (double pos = from; pos <= to; pos += step) {
            addPosition(pos);
        }
    }
}

void PositionConfigDialog::onDeleteClicked() {
    int currentRow = m_tableWidget->currentRow();
    if (currentRow >= 0 && currentRow < m_positions.size()) {
        m_positions.removeAt(currentRow);
        refreshTable();
    }
}

void PositionConfigDialog::onMoveUpClicked() {
    int currentRow = m_tableWidget->currentRow();
    if (currentRow > 0) {
        m_positions.swapItemsAt(currentRow, currentRow - 1);
        refreshTable();
        m_tableWidget->selectRow(currentRow - 1);
    }
}

void PositionConfigDialog::onMoveDownClicked() {
    int currentRow = m_tableWidget->currentRow();
    if (currentRow >= 0 && currentRow < m_positions.size() - 1) {
        m_positions.swapItemsAt(currentRow, currentRow + 1);
        refreshTable();
        m_tableWidget->selectRow(currentRow + 1);
    }
}

void PositionConfigDialog::onSortAscendingClicked() {
    std::sort(m_positions.begin(), m_positions.end());
    refreshTable();
}

void PositionConfigDialog::onSortDescendingClicked() {
    std::sort(m_positions.begin(), m_positions.end(), std::greater<double>());
    refreshTable();
}

void PositionConfigDialog::addPosition(double position) {
    m_positions.append(position);
    refreshTable();
    m_tableWidget->selectRow(m_positions.size() - 1);
}

void PositionConfigDialog::refreshTable() {
    m_tableWidget->setRowCount(m_positions.size());
    for (int i = 0; i < m_positions.size(); ++i) {
        auto *numberItem = new QTableWidgetItem(QString::number(i + 1));
        numberItem->setFlags(numberItem->flags() & ~Qt::ItemIsEditable);
        m_tableWidget->setItem(i, 0, numberItem);
        auto *positionItem = new QTableWidgetItem(QString::number(m_positions[i], 'f', 3));
        m_tableWidget->setItem(i, 1, positionItem);
    }
    updateButtons();
}

void PositionConfigDialog::updateButtons() {
    bool hasSelection = m_tableWidget->currentRow() >= 0;
    bool hasItems = !m_positions.isEmpty();
    int currentRow = m_tableWidget->currentRow();
    m_deleteButton->setEnabled(hasSelection);
    m_moveUpButton->setEnabled(hasSelection && currentRow > 0);
    m_moveDownButton->setEnabled(hasSelection && currentRow < m_positions.size() - 1);
    m_sortAscButton->setEnabled(hasItems);
    m_sortDescButton->setEnabled(hasItems);
    m_clearButton->setEnabled(hasItems);
}
